<!doctype html>



  


<html class="theme-next mist use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>



<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />















  
  
    
  
  <link href="//cdn.jsdelivr.net/fancybox/2.1.5/jquery.fancybox.min.css" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  

  

  

  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






  

<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.6.2/css/font-awesome.min.css" rel="stylesheet" type="text/css" />

<link href="/css/main.css?v=5.1.0" rel="stylesheet" type="text/css" />


  <meta name="keywords" content="springmvc," />








  <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico?v=5.1.0" />






<meta name="description" content="Spring的Jar包依赖和配置文件的设置Post请求中的中文乱码解决方案&amp;lt;filter&amp;gt;    &amp;lt;filter-name&amp;gt;CharacterEncodingFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/">
<meta property="og:type" content="article">
<meta property="og:title" content="SpringMVC基础学习(一)">
<meta property="og:url" content="https://zitongchen.github.io/2017/08/14/SpringMVC基础学习(一)/index.html">
<meta property="og:site_name" content="Tony's Notes">
<meta property="og:description" content="Spring的Jar包依赖和配置文件的设置Post请求中的中文乱码解决方案&amp;lt;filter&amp;gt;    &amp;lt;filter-name&amp;gt;CharacterEncodingFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/">
<meta property="og:image" content="https://static.oschina.net/uploads/img/201708/13161048_4lGq.jpg">
<meta property="og:image" content="https://static.oschina.net/uploads/img/201708/13161113_vlVk.jpg">
<meta property="og:image" content="https://static.oschina.net/uploads/img/201708/13162403_dCY4.jpg">
<meta property="og:image" content="https://static.oschina.net/uploads/img/201708/13162459_oJlQ.jpg">
<meta property="og:image" content="https://static.oschina.net/uploads/img/201708/13162711_iXjE.jpg">
<meta property="og:updated_time" content="2017-09-16T10:13:29.837Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="SpringMVC基础学习(一)">
<meta name="twitter:description" content="Spring的Jar包依赖和配置文件的设置Post请求中的中文乱码解决方案&amp;lt;filter&amp;gt;    &amp;lt;filter-name&amp;gt;CharacterEncodingFilter&amp;lt;/filter-name&amp;gt;    &amp;lt;filter-class&amp;gt;org.springframework.web.filter.CharacterEncodingFilter&amp;lt;/">
<meta name="twitter:image" content="https://static.oschina.net/uploads/img/201708/13161048_4lGq.jpg">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/',
    scheme: 'Mist',
    sidebar: {"position":"left","display":"post","offset":12,"offset_float":0,"b2t":false,"scrollpercent":false},
    fancybox: true,
    motion: true,
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="https://zitongchen.github.io/2017/08/14/SpringMVC基础学习(一)/"/>





  <title> SpringMVC基础学习(一) | Tony's Notes </title>
</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  














  
  
    
  

  <div class="container one-collumn sidebar-position-left page-post-detail ">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Tony's Notes</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle"></p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/archives" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/categories" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/tags" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/about" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      

      
    </ul>
  

  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal " itemscope itemtype="http://schema.org/Article">
    <link itemprop="mainEntityOfPage" href="https://zitongchen.github.io/2017/08/14/SpringMVC基础学习(一)/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Tony">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/images/avater.png">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Tony's Notes">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">
            
            
              
                SpringMVC基础学习(一)
              
            
          </h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2017-08-14T00:00:00+08:00">
                2017-08-14
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/categories/Spring/" itemprop="url" rel="index">
                    <span itemprop="name">Spring</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          
             <span id="/2017/08/14/SpringMVC基础学习(一)/" class="leancloud_visitors" data-flag-title="SpringMVC基础学习(一)">
               <span class="post-meta-divider">|</span>
               <span class="post-meta-item-icon">
                 <i class="fa fa-eye"></i>
               </span>
               
                 <span class="post-meta-item-text">阅读次数 </span>
               
                 <span class="leancloud-visitors-count"></span>
             </span>
          

          

          

          

        </div>
      </header>
    


    <div class="post-body" itemprop="articleBody">

      
      

      
        <h1 id="Spring的Jar包依赖和配置文件的设置"><a href="#Spring的Jar包依赖和配置文件的设置" class="headerlink" title="Spring的Jar包依赖和配置文件的设置"></a>Spring的Jar包依赖和配置文件的设置</h1><p>Post请求中的中文乱码解决方案<br><figure class="highlight xml"><table><tr><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">filter</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">filter-name</span>&gt;</span>CharacterEncodingFilter<span class="tag">&lt;/<span class="name">filter-name</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">filter-class</span>&gt;</span>org.springframework.web.filter.CharacterEncodingFilter<span class="tag">&lt;/<span class="name">filter-class</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></div><div class="line">    	<span class="tag">&lt;<span class="name">param-name</span>&gt;</span>encoding<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></div><div class="line">    	<span class="tag">&lt;<span class="name">param-value</span>&gt;</span>utf-8<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">filter</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">filter-mapping</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">filter-name</span>&gt;</span>CharacterEncodingFilter<span class="tag">&lt;/<span class="name">filter-name</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/*<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">filter-mapping</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>SpringMVC框架在容器中的执</p>
<p><img src="https://static.oschina.net/uploads/img/201708/13161048_4lGq.jpg" alt="输入图片说明" title="在这里输入图片标题"></p>
<p>DispatcherServlet控制器的执行流程</p>
<p><img src="https://static.oschina.net/uploads/img/201708/13161113_vlVk.jpg" alt="输入图片说明" title="在这里输入图片标题"></p>
<p>SpingMvc在web.xml的配置<br><figure class="highlight xml"><table><tr><td class="code"><pre><div class="line"><span class="comment">&lt;!--配置DispatcherServlet--&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">servlet</span>&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>lifestyle-dispatcher<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">servlet-class</span>&gt;</span>org.springframework.web.servlet.DispatcherServlet<span class="tag">&lt;/<span class="name">servlet-class</span>&gt;</span></div><div class="line">        <span class="comment">&lt;!--</span></div><div class="line">            配制SpringMVC需要的配置文件:</div><div class="line">            spring-dao.xml,spring-service.xml,spring-web.xml</div><div class="line">            Mybatis -&gt; spring -&gt; springMvc</div><div class="line">        --&gt;</div><div class="line">        <span class="tag">&lt;<span class="name">init-param</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></div><div class="line">            <span class="tag">&lt;<span class="name">param-value</span>&gt;</span>classpath:spring/spring-*.xml<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></div><div class="line">        <span class="tag">&lt;/<span class="name">init-param</span>&gt;</span></div><div class="line">       <span class="tag">&lt;<span class="name">load-on-startup</span>&gt;</span>1<span class="tag">&lt;/<span class="name">load-on-startup</span>&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">servlet</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">servlet-mapping</span>&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">servlet-name</span>&gt;</span>lifestyle-dispatcher<span class="tag">&lt;/<span class="name">servlet-name</span>&gt;</span></div><div class="line">        <span class="comment">&lt;!--默认的匹配所以请求--&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">url-pattern</span>&gt;</span>/<span class="tag">&lt;/<span class="name">url-pattern</span>&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">servlet-mapping</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>Spring Web MVC框架中，需要配置Sping的配置文件：</p>
<p>默认DispatcherServlet会自动加载WEB-INF/[DispatcherServlet 的 Servlet 名 字 ]-servlet.xml配置文件 ,上述的默认加载路径为：WEB-INF/lifestyle-dispatcher-servlet.xml,若想改变默认加载路径需要初始化DispatcherServlet的contextConfigLocaltion属性</p>
<p>sping集成web框架的通用配置：<br><figure class="highlight xml"><table><tr><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">context-param</span>&gt;</span></div><div class="line">  	<span class="tag">&lt;<span class="name">param-name</span>&gt;</span>contextConfigLocation<span class="tag">&lt;/<span class="name">param-name</span>&gt;</span></div><div class="line">  	<span class="tag">&lt;<span class="name">param-value</span>&gt;</span></div><div class="line">      classpath:spring-common-config.xml,</div><div class="line">      classpath:spring-budget-config.xml</div><div class="line">  	<span class="tag">&lt;/<span class="name">param-value</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">context-param</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">listener</span>&gt;</span></div><div class="line">	<span class="tag">&lt;<span class="name">listener-class</span>&gt;</span>org.springframework.web.context.ContextLoaderListener<span class="tag">&lt;/<span class="name">listener-class</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">listener</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>SpringMVC中DispatcherServlet的配置文件：<br><figure class="highlight xml"><table><tr><td class="code"><pre><div class="line">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</div><div class="line"><span class="tag">&lt;<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></div><div class="line">       <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></div><div class="line">       <span class="attr">xmlns:context</span>=<span class="string">"http://www.springframework.org/schema/context"</span></div><div class="line">       <span class="attr">xmlns:mvc</span>=<span class="string">"http://www.springframework.org/schema/mvc"</span></div><div class="line">       <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans</span></div><div class="line">        http://www.springframework.org/schema/beans/spring-beans.xsd</div><div class="line">        http://www.springframework.org/schema/context</div><div class="line">        http://www.springframework.org/schema/context/spring-context.xsd</div><div class="line">        http://www.springframework.org/schema/mvc</div><div class="line">        http://www.springframework.org/schema/mvc/spring-mvc.xsd"&gt;</div><div class="line">    <span class="comment">&lt;!--配置spring mvc--&gt;</span></div><div class="line">    <span class="comment">&lt;!--1，开启springmvc注解模式</span></div><div class="line">    a.自动注册DefaultAnnotationHandlerMapping,AnnotationMethodHandlerAdapter(spring3.1之前)</div><div class="line">    b.默认提供一系列的功能：数据绑定，数字和日期format@NumberFormat,@DateTimeFormat</div><div class="line">    c.xml,json的默认读写支持</div><div class="line">    --&gt;</div><div class="line">    <span class="tag">&lt;<span class="name">mvc:annotation-driven</span> <span class="attr">validator</span>=<span class="string">"validator"</span>/&gt;</span></div><div class="line"></div><div class="line">	<span class="comment">&lt;!-- 开启数据校验 --&gt;</span></div><div class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"validator"</span></span></div><div class="line">		<span class="attr">class</span>=<span class="string">"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"</span>&gt;</div><div class="line">		<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"providerClass"</span> <span class="attr">value</span>=<span class="string">"org.hibernate.validator.HibernateValidator"</span> /&gt;</span></div><div class="line">		<span class="comment">&lt;!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties --&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"validationMessageSource"</span> <span class="attr">ref</span>=<span class="string">"messageSource"</span> /&gt;</span></div><div class="line">	<span class="tag">&lt;/<span class="name">bean</span>&gt;</span></div><div class="line">	<span class="comment">&lt;!-- 数据校验的文件 --&gt;</span></div><div class="line">  	<span class="comment">&lt;!--ReloadableResourceBundleMessageSource可以重新加载属性文件，下面的应用中的实现需要重启JVM才能重新加载属性文件--&gt;</span></div><div class="line">	<span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"messageSource"</span> <span class="attr">class</span>=<span class="string">"org.springframework.context.support.ResourceBundleMessageSource"</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"basename"</span> <span class="attr">value</span>=<span class="string">"i18n/messages"</span>/&gt;</span>	</div><div class="line">	<span class="tag">&lt;/<span class="name">bean</span>&gt;</span></div><div class="line">    <span class="comment">&lt;!--2.静态资源默认servlet配置，使用servlet来相应静态文件--&gt;</span></div><div class="line">    <span class="comment">&lt;!--</span></div><div class="line">        1.加入对静态资源处理：js,gif,png</div><div class="line">        2.允许使用“/”做整体映射</div><div class="line">    --&gt;</div><div class="line">    <span class="tag">&lt;<span class="name">mvc:default-servlet-handler</span>/&gt;</span></div><div class="line">    <span class="comment">&lt;!--3:配置jsp显示viewResolver--&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"org.springframework.web.servlet.view.InternalResourceViewResolver"</span>&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"viewClass"</span> <span class="attr">value</span>=<span class="string">"org.springframework.web.servlet.view.JstlView"</span>/&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"prefix"</span> <span class="attr">value</span>=<span class="string">"/WEB-INF/jsp/"</span>/&gt;</span></div><div class="line">        <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"suffix"</span> <span class="attr">value</span>=<span class="string">".jsp"</span>/&gt;</span></div><div class="line">    <span class="tag">&lt;/<span class="name">bean</span>&gt;</span></div><div class="line"></div><div class="line">    <span class="comment">&lt;!--4：扫描web相关的bean--&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">context:component-scan</span> <span class="attr">base-package</span>=<span class="string">"cc.codingape.web"</span>/&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">beans</span>&gt;</span></div></pre></td></tr></table></figure></p>
<h1 id="注解控制器"><a href="#注解控制器" class="headerlink" title="注解控制器"></a>注解控制器</h1><h2 id="Spring2-5引入注解式的处理器"><a href="#Spring2-5引入注解式的处理器" class="headerlink" title="Spring2.5引入注解式的处理器"></a>Spring2.5引入注解式的处理器</h2><ul>
<li><p><a href="https://my.oschina.net/u/1774615" target="_blank" rel="external">@Controller</a>:用于标识处理器</p>
</li>
<li><p>@RequestMapping:处理器功能映射</p>
</li>
<li><p>@RequestParam:请求参数到处理器功能方法参数上的绑定</p>
</li>
<li><p>@ModelAttribute:请求参数到命令对象的绑定</p>
</li>
<li><p>@SessionAttribute:用于声明session级别储存的 属性，放置在类处理器上，通常列出模型属性对应的名称</p>
</li>
</ul>
<h2 id="Spring3-0引入RESTful架构风格的支持"><a href="#Spring3-0引入RESTful架构风格的支持" class="headerlink" title="Spring3.0引入RESTful架构风格的支持"></a>Spring3.0引入RESTful架构风格的支持</h2><ul>
<li><p>@CookieValue:cookie数据到处理器功能方法参数上的绑定</p>
</li>
<li><p>@RequestHeader:请求头数据到处理器功能方法参数上的绑定</p>
</li>
<li><p>@RequestBody:请求的body体的绑定</p>
</li>
<li><p>@ResponseBody:处理器功能方法返回值作为响应体</p>
</li>
<li><p>@ResponseStatus:定义处理器过年处理方法、异常处理器返回的状态码和原因</p>
</li>
<li><p>@ExceptionHandler:注解式声明异常处理器</p>
</li>
<li><p>@PathVariable:请求URI中的模板变量部分到功能处理器功能处理方法上的绑定</p>
</li>
</ul>
<h2 id="请求数据绑定"><a href="#请求数据绑定" class="headerlink" title="请求数据绑定"></a>请求数据绑定</h2><figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="comment">//定义处理器</span></div><div class="line"><span class="meta">@Controller</span></div><div class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/controller"</span>) <span class="comment">//定义类的映射路径为/controller</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ParamsControllerTest</span> </span>&#123;</div><div class="line">	<span class="comment">//定义方法路径与处理器功能上的映射,method的值表示可以接受get或post的请求</span></div><div class="line">  	<span class="comment">//类映射路径与方法路径结合，进行路径的窄化，通过 应用名称/controller/hello可以访问下述方法</span></div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"/hello"</span>,method = &#123;RequestMethod.GET,RequestMethod.POST&#125;)</div><div class="line">	<span class="function"><span class="keyword">public</span> ModelAndView <span class="title">helloWorld</span><span class="params">(ModelAndView model)</span></span>&#123;</div><div class="line">		model.addObject(<span class="string">"message"</span>, <span class="string">"Hello World"</span>);</div><div class="line">		model.setViewName(<span class="string">"hello"</span>);<span class="comment">//处置视图模型的名称</span></div><div class="line">		<span class="keyword">return</span> model;<span class="comment">//返回模型视图</span></div><div class="line">	&#125;</div><div class="line">  </div><div class="line">  <span class="comment">//ant风格的方法路径映射，value的值表示可以通过/antTest/* 或 /ant/* 都可以访问到antTest方法，并返回视图的名称</span></div><div class="line">	<span class="meta">@RequestMapping</span>(value=&#123;<span class="string">"/antTest/*"</span>,<span class="string">"/ant/*"</span>&#125; ,method=RequestMethod.GET)</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">antTest</span><span class="params">(WebRequest request)</span></span>&#123;</div><div class="line">		request.setAttribute(<span class="string">"message"</span>, <span class="string">"ant test"</span>, WebRequest.SCOPE_REQUEST);</div><div class="line">		<span class="keyword">return</span> <span class="string">"hello"</span>;</div><div class="line">	&#125;</div><div class="line">  </div><div class="line"> 	 <span class="comment">/*</span></div><div class="line">	 * 该方法的访问路径为../param?username=tony  同时params="!hello"表示../param?!hello匹配该方法</div><div class="line">	 * params使用的是且关系：params=&#123;"username=tony", "password"&#125;</div><div class="line">	 * 表示路径 ../param?username=tony&amp;password</div><div class="line">	 */</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"/param"</span>,params=<span class="string">"username=tony"</span>,method = RequestMethod.GET)</div><div class="line">	<span class="function"><span class="keyword">public</span> ModelAndView <span class="title">paramTest</span><span class="params">(ModelAndView model)</span></span>&#123;</div><div class="line">		model.addObject(<span class="string">"message"</span>,<span class="string">"paramTest class"</span>);</div><div class="line">		model.setViewName(<span class="string">"hello"</span>);</div><div class="line">		<span class="keyword">return</span> model;</div><div class="line">	&#125;</div><div class="line">  </div><div class="line">  	<span class="comment">/*@RequestParam路径属性到方法属性上的绑定，../requestParam?username=tony，匹配到该方法</span></div><div class="line">	 * required=false表示访问路径中不存在username属性 路径 ../requestParam也可以方法到该方法</div><div class="line">	 * required=true 则必须路径中存在username属性值才可以访问到该方法</div><div class="line">	 * defalutValue 表示若username不存在值时使用的默认值</div><div class="line">	 */</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"/requestParam"</span>,method=RequestMethod.GET)</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">requestParamTest</span><span class="params">(@RequestParam(value=<span class="string">"username"</span>,required=<span class="keyword">false</span>,</span></span></div><div class="line">                                                 defaultValue=<span class="string">""</span>)String username,Model model)&#123;</div><div class="line">		model.addAttribute(<span class="string">"message"</span>, username);</div><div class="line">		<span class="keyword">return</span> <span class="string">"hello"</span>;</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>WebRequest 是 Spring Web MVC 提供的统一请求访问接口，不仅仅可以访问请求相关数据（如参数区数据、请求头数据，但访问不到 Cookie 区数据），还可以访问会话和上下文中的数据 ；WebRequest具有三个作业范围NativeWebRequest 继承了 WebRequest，并提供访问本地 Servlet API 的方法。nativeWebRequest.getNativeRequest/nativeWebRequest.getNativeResponse：得到本地的 Servlet API  </p>
<h2 id="Json返回类型"><a href="#Json返回类型" class="headerlink" title="Json返回类型"></a>Json返回类型</h2><figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="meta">@Controller</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JsonController</span> </span>&#123;</div><div class="line">  	<span class="comment">/*</span></div><div class="line">  	访问/getJson路径返回json类型的user对象</div><div class="line">     */</div><div class="line">	<span class="meta">@ResponseBody</span></div><div class="line">	<span class="meta">@RequestMapping</span>(<span class="string">"/getJson"</span>)</div><div class="line">	<span class="function"><span class="keyword">public</span> User <span class="title">getUserInfo</span><span class="params">()</span></span>&#123;</div><div class="line">		User user = <span class="keyword">new</span> User();</div><div class="line">		user.setPassword(<span class="string">"1234"</span>);</div><div class="line">		user.setUsername(<span class="string">"jsontest"</span>);</div><div class="line">		<span class="keyword">return</span> user;</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<h2 id="ModelAttribute-amp-SessionAttribute"><a href="#ModelAttribute-amp-SessionAttribute" class="headerlink" title="@ModelAttribute &amp; @SessionAttribute"></a>@ModelAttribute &amp; @SessionAttribute</h2><p>@ModelAttribute注解：</p>
<ul>
<li><p>绑定请求参数到命令对象</p>
<figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="meta">@RequestMapping</span>(value=<span class="string">"/model2/&#123;username&#125;"</span>)</div><div class="line"><span class="function"><span class="keyword">public</span> String <span class="title">test2</span><span class="params">(@ModelAttribute(<span class="string">"model"</span>)</span> DataBinderTestModel model) </span>&#123;｝</div></pre></td></tr></table></figure>
</li>
<li><p>暴露表单应用对象为模型数据</p>
<figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="meta">@ModelAttribute</span>(<span class="string">"cityList"</span>)</div><div class="line">  <span class="function"><span class="keyword">public</span> List&lt;String&gt; <span class="title">cityList</span><span class="params">()</span> </span>&#123;</div><div class="line">  <span class="keyword">return</span> Arrays.asList(<span class="string">"北京"</span>, <span class="string">"山东"</span>);</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
<li><p>暴露@RequesMapping方法返回值为模型数据（返回值的同名Model会覆盖参数的同名Model）</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><div class="line">public @ModelAttribute(&quot;user2&quot;) UserModel test3(@ModelAttribute(&quot;user2&quot;) UserModel user)</div></pre></td></tr></table></figure>
</li>
</ul>
<p>@ModelAttribute 和 @SessionAttribute的结合<br><figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="comment">//1.在session中设置一个名为user的属性</span></div><div class="line"><span class="meta">@SessionAttributes</span>(value=&#123;<span class="string">"user"</span>&#125;)</div><div class="line"><span class="meta">@Controller</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ControllerTest</span> </span>&#123;</div><div class="line">	<span class="comment">/*2.</span></div><div class="line">	 * 若是使用了@SessionAttributes注解，会在回话中查找同名的参数</div><div class="line">	 * 若没有就必须要使用@ModelAttribute产生一个同名的属性到数据模型中,</div><div class="line">	 * 并把user对象放到session中</div><div class="line">	 */</div><div class="line">	<span class="meta">@ModelAttribute</span>(<span class="string">"user"</span>)</div><div class="line">	<span class="function"><span class="keyword">public</span> User <span class="title">getUser</span><span class="params">()</span></span>&#123;</div><div class="line">		User user = <span class="keyword">new</span> User();</div><div class="line">		user.setUsername(<span class="string">"chenzitong"</span>);</div><div class="line">		user.setPassword(<span class="string">"123"</span>);</div><div class="line">		<span class="keyword">return</span> user;</div><div class="line">	&#125;</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"/session/login"</span>,method=RequestMethod.GET)</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">login</span><span class="params">()</span></span>&#123;</div><div class="line">		<span class="keyword">return</span> <span class="string">"login"</span>;</div><div class="line">	&#125;</div><div class="line">	<span class="comment">/*3.</span></div><div class="line">	 * 这里的@ModelAttribute会读取输入的参数并绑定到user对象中，同时更新session的同名对象</div><div class="line">	 */</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"/session/login"</span>,method = RequestMethod.POST)</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">loginSystem</span><span class="params">(@ModelAttribute(<span class="string">"user"</span>)</span> User user,ModelMap map)</span>&#123;</div><div class="line">		<span class="comment">//map.addAttribute("User", user);</span></div><div class="line">		<span class="keyword">return</span> <span class="string">"success"</span>;</div><div class="line">	&#125;</div><div class="line">	<span class="comment">/*4.</span></div><div class="line">	 * 清除session属性</div><div class="line">	 */</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"session/doLoginOut"</span>,method=RequestMethod.GET)</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">doLoginOut</span><span class="params">(SessionStatus session)</span></span>&#123;</div><div class="line">		session.setComplete();</div><div class="line">		<span class="keyword">return</span> <span class="string">"login"</span>;</div><div class="line">	&#125;</div></pre></td></tr></table></figure></p>
<p>在处理器中使用@SessionAttribute注解，1.先在session回话中查找同名对象，2.若没有查找到，需要使用@ModelAttribute构建一个同名的对象 3.若方法参数的Model跟session的同名会根据请求的参数更新session的同名对象</p>
<h1 id="拦截器"><a href="#拦截器" class="headerlink" title="拦截器"></a>拦截器</h1><p>拦截器功能：</p>
<ul>
<li>日记记录</li>
<li>性能监控</li>
<li>权限验证</li>
<li>通用行为:提取cookie等</li>
</ul>
<p>springMvc中的Interceptor拦截请求通过HandlerInterceptor来实现：</p>
<ul>
<li>定义Interceptor类实现Spring的HandlerInterceptor接口</li>
<li>继承实现了HandlerInterceptor接口的抽象类,例如：HandlerInterceptorAdapter类</li>
</ul>
<p>HandlerInterceptor有三个方法：</p>
<ul>
<li>perHandle(…),在请求处理之前调用（顺序执行）</li>
<li>postHandle(…),在请求处理之后调用（倒序执行）</li>
<li>afterCompletion(….),在整个请求结束之后调用(渲染视图之后)-倒序执行</li>
</ul>
<h2 id="拦截器执行顺序"><a href="#拦截器执行顺序" class="headerlink" title="拦截器执行顺序"></a>拦截器执行顺序</h2><p>正常的执行顺序：</p>
<p><img src="https://static.oschina.net/uploads/img/201708/13162403_dCY4.jpg" alt="输入图片说明" title="在这里输入图片标题"></p>
<p>发生异常中断的执行顺序：</p>
<p><img src="https://static.oschina.net/uploads/img/201708/13162459_oJlQ.jpg" alt="输入图片说明" title="在这里输入图片标题"></p>
<p>实现了HandlerInterceptor的拦截器：<br><figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="keyword">package</span> cc.codingape.web;</div><div class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletRequest;</div><div class="line"><span class="keyword">import</span> javax.servlet.http.HttpServletResponse;</div><div class="line"><span class="keyword">import</span> org.springframework.web.servlet.HandlerInterceptor;</div><div class="line"><span class="keyword">import</span> org.springframework.web.servlet.ModelAndView;</div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">UserInterceptor</span> <span class="keyword">implements</span> <span class="title">HandlerInterceptor</span> </span>&#123;</div><div class="line">	<span class="meta">@Override</span></div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">preHandle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler)</span></span></div><div class="line">			<span class="keyword">throws</span> Exception &#123;</div><div class="line">		<span class="comment">// TODO Auto-generated method stub</span></div><div class="line">		<span class="keyword">return</span> <span class="keyword">false</span>;</div><div class="line">	&#125;</div><div class="line">	<span class="meta">@Override</span></div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">postHandle</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler,</span></span></div><div class="line">			ModelAndView modelAndView) <span class="keyword">throws</span> Exception &#123;</div><div class="line">		<span class="comment">// TODO Auto-generated method stub</span></div><div class="line"></div><div class="line">	&#125;</div><div class="line">	<span class="meta">@Override</span></div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterCompletion</span><span class="params">(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)</span></span></div><div class="line">			<span class="keyword">throws</span> Exception &#123;</div><div class="line">		<span class="comment">// TODO Auto-generated method stub</span></div><div class="line"></div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>拦截器在springmvc的配置：<br><figure class="highlight xml"><table><tr><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">mvc:interceptors</span>&gt;</span>  </div><div class="line">    	<span class="comment">&lt;!-- 使用bean定义一个Interceptor，直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 --&gt;</span>  </div><div class="line">    	 <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"拦截器类路径"</span>/&gt;</span></div><div class="line">	    <span class="tag">&lt;<span class="name">mvc:interceptor</span>&gt;</span>  </div><div class="line">	        <span class="tag">&lt;<span class="name">mvc:mapping</span> <span class="attr">path</span>=<span class="string">"/user/**"</span>/&gt;</span>  </div><div class="line">	        <span class="comment">&lt;!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 --&gt;</span>  </div><div class="line">	        <span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"cc.codingape.interceptor.UserInterceptor"</span>/&gt;</span>  </div><div class="line">	    <span class="tag">&lt;/<span class="name">mvc:interceptor</span>&gt;</span>  </div><div class="line">	<span class="tag">&lt;/<span class="name">mvc:interceptors</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>推荐能用servlet规范中的过滤器Filter实现的功能就用Filter实现，因为HandlerInterceptor只有在SpringWeb mvc环境下使用，因此Filter是最通用，最先 应该使用。如登录验证</p>
<h1 id="统一异常处理"><a href="#统一异常处理" class="headerlink" title="统一异常处理"></a>统一异常处理</h1><p><img src="https://static.oschina.net/uploads/img/201708/13162711_iXjE.jpg" alt="输入图片说明" title="在这里输入图片标题"></p>
<p>SpringMVC提供的全局异常处理器（一个系统只有一个异常处理器），进行统一的处理。</p>
<p>SpringMVC中异常处理的三中方式：</p>
<ul>
<li>使用Spring MVC提供的简单异常处理器SimpleMappingExceptionResolver<figure class="highlight xml"><table><tr><td class="code"><pre><div class="line"><span class="comment">&lt;!-- springmvc提供的简单异常处理器 --&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"</span>&gt;</span></div><div class="line">  <span class="comment">&lt;!-- 定义默认的异常处理页面 --&gt;</span></div><div class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"defaultErrorView"</span> <span class="attr">value</span>=<span class="string">"/WEB-INF/jsp/error.jsp"</span>/&gt;</span></div><div class="line"> <span class="comment">&lt;!-- 定义异常处理页面用来获取异常信息的变量名，也可不定义，默认名为exception --&gt;</span> </div><div class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"exceptionAttribute"</span> <span class="attr">value</span>=<span class="string">"ex"</span>/&gt;</span></div><div class="line"> <span class="comment">&lt;!-- 定义需要特殊处理的异常，这是重要点,异常类作为key,错误页面作为值 --&gt;</span> </div><div class="line"> <span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"exceptionMappings"</span>&gt;</span></div><div class="line">    <span class="tag">&lt;<span class="name">props</span>&gt;</span></div><div class="line">         <span class="tag">&lt;<span class="name">prop</span> <span class="attr">key</span>=<span class="string">"ssm.exception.CustomException"</span>&gt;</span>/WEB-INF/jsp/custom_error.jsp<span class="tag">&lt;/<span class="name">prop</span>&gt;</span></div><div class="line">            <span class="comment">&lt;!-- 还可以定义其他的自定义异常 --&gt;</span></div><div class="line">     <span class="tag">&lt;/<span class="name">props</span>&gt;</span></div><div class="line">   <span class="tag">&lt;/<span class="name">property</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></div></pre></td></tr></table></figure>
</li>
</ul>
<p>该统一异常处理器集成简单，对已有代码没有入侵，但该方法仅能获取异常信息，不能获取其他数据信息</p>
<ul>
<li>实现Spring的异常处理接口HandlerExceptionResolver自定义全局异常处理器,处理器处理的异常可以是系统异常，也可以是实现了Exception的自定义异常<figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CustomExceptionResolver</span> <span class="keyword">implements</span> <span class="title">HandlerExceptionResolver</span> </span>&#123;</div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> ModelAndView <span class="title">resolveException</span><span class="params">(HttpServletRequest request,</span></span></div><div class="line">            HttpServletResponse response, Object handler, Exception ex) &#123;</div><div class="line">        CustomException customException = <span class="keyword">null</span>;</div><div class="line">        <span class="comment">//如果抛出的是系统自定义的异常则直接转换</span></div><div class="line">        <span class="keyword">if</span>(ex <span class="keyword">instanceof</span> CustomException) &#123;</div><div class="line">            customException = (CustomException) ex;</div><div class="line">        &#125; <span class="keyword">else</span> &#123;</div><div class="line">            <span class="comment">//如果抛出的不是系统自定义的异常则重新构造一个未知错误异常</span></div><div class="line">            <span class="comment">//这里我就也有CustomException省事了，实际中应该要再定义一个新的异常</span></div><div class="line">            customException = <span class="keyword">new</span> CustomException(<span class="string">"系统未知错误"</span>);</div><div class="line">        &#125;</div><div class="line">        <span class="comment">//向前台返回错误信息</span></div><div class="line">        ModelAndView modelAndView = <span class="keyword">new</span> ModelAndView();</div><div class="line">        modelAndView.addObject(<span class="string">"message"</span>, customException.getMessage());</div><div class="line">        modelAndView.setViewName(<span class="string">"/WEB-INF/jsp/error.jsp"</span>);</div><div class="line">        <span class="keyword">return</span> modelAndView;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
</ul>
<p>该异常处理器需要在SpringMVC配置文件中声明：<br><figure class="highlight plain"><table><tr><td class="code"><pre><div class="line">&lt;!-- 自定义的全局异常处理器 </div><div class="line">只要实现HandlerExceptionResolver接口就是全局异常处理器--&gt;</div><div class="line">&lt;bean  class=&quot;ssm.exception.CustomExceptionResolver&quot;&gt;&lt;/bean&gt;</div></pre></td></tr></table></figure></p>
<ul>
<li>使用@ExceptionHandler注解实现异常处理，对代码入侵较大，需要先写一个BaseController类，并用@ExceptionHandler注解声明异常处理的方法<figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BaseController</span> </span>&#123; </div><div class="line">   <span class="meta">@ExceptionHandler</span></div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">exp</span><span class="params">(HttpServletRequest request, Exception ex)</span></span>&#123;</div><div class="line">		<span class="keyword">if</span>(ex <span class="keyword">instanceof</span> MyException)&#123;</div><div class="line">			request.setAttribute(<span class="string">"errorMessage"</span>, ex.getMessage());</div><div class="line">			<span class="keyword">return</span> <span class="string">"error"</span>;</div><div class="line">		&#125;<span class="keyword">else</span>&#123;</div><div class="line">          <span class="keyword">return</span> <span class="string">"other_error"</span>;</div><div class="line">		&#125;</div><div class="line">      <span class="comment">//异常处理</span></div><div class="line">    <span class="comment">//......</span></div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
</li>
</ul>
<p>控制器需要继承BaseController类<br><figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="meta">@Controller</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ExceptionController</span> <span class="keyword">extends</span> <span class="title">BaseController</span> </span>&#123;</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"testException"</span>,method = RequestMethod.GET)</div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testException</span><span class="params">()</span> <span class="keyword">throws</span> MyException</span>&#123;</div><div class="line">		<span class="keyword">throw</span> <span class="keyword">new</span> MyException(<span class="string">"springmvc exception test"</span>);</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<p>自定义异常MyException类<br><figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">MyException</span> <span class="keyword">extends</span> <span class="title">Exception</span> </span>&#123;</div><div class="line">	<span class="keyword">private</span> String message;</div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="title">MyException</span><span class="params">(String message)</span> </span>&#123;</div><div class="line">		<span class="keyword">super</span>();</div><div class="line">		<span class="keyword">this</span>.message = message;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getMessage</span><span class="params">()</span> </span>&#123;</div><div class="line">		<span class="keyword">return</span> message;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setMessage</span><span class="params">(String message)</span> </span>&#123;</div><div class="line">		<span class="keyword">this</span>.message = message;</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p>
<h1 id="数据验证"><a href="#数据验证" class="headerlink" title="数据验证"></a>数据验证</h1><h2 id="JSR303-校验框架介绍："><a href="#JSR303-校验框架介绍：" class="headerlink" title="JSR303 校验框架介绍："></a>JSR303 校验框架介绍：</h2><ul>
<li><p>JSR 303 用于对Java Bean 中的字段的值进行验证,使得验证逻辑从业务代码中脱离出来</p>
</li>
<li><p>是一个运行时的数据验证框架，在验证之后验证的错误信息会被马上返回</p>
</li>
<li><p>一般用于表单提交页面(如用户名必填、只能由数字字母组成等等)</p>
</li>
</ul>
<h2 id="JSR303-校验框架注解类："><a href="#JSR303-校验框架注解类：" class="headerlink" title="JSR303 校验框架注解类："></a>JSR303 校验框架注解类：</h2><ul>
<li><p>@NotNull  注解元素必须是非空    任意类型</p>
<ul>
<li><p>@Null  注解元素必须是空    任意类型</p>
</li>
<li><p>@Digits  验证数字构成是否合法@Digits(integer = 整数,fraction=小数)，数字类型的</p>
</li>
</ul>
</li>
<li><p>@Future  验证是否在当前系统时间之后</p>
</li>
<li><p>@Past  验证是否在当前系统时间之前</p>
<ul>
<li><p>@Max  验证值是否小于等于最大指定整数值    @Max(value=值) ，数字类型</p>
<ul>
<li>@Min  验证值是否大于等于最小指定整数值同@Max</li>
</ul>
</li>
</ul>
</li>
<li><p>@Pattern  验证字符串是否匹配指定的正则表达式</p>
<ul>
<li><p>@Size  验证元素大小是否在指定范围内    @Size(min = 下限, max= 上限)</p>
</li>
<li><p>@DecimalMax  验证值是否小于等于最大指定小数值同@Max</p>
</li>
<li><p>@DecimalMin  验证值是否大于等于最小指定小数值同@Max</p>
</li>
</ul>
</li>
<li><p>@AssertTrue  被注释的元素必须为true</p>
</li>
<li><p>@AssertFalse  被注释的元素必须为false</p>
</li>
</ul>
<h2 id="HibernateValidator扩展注解类："><a href="#HibernateValidator扩展注解类：" class="headerlink" title="HibernateValidator扩展注解类："></a>HibernateValidator扩展注解类：</h2><ul>
<li><p>@Email  被注释的元素必须是电子邮箱地址    @Email(regexp=正则表达式)</p>
<ul>
<li><p>@Length  被注释的字符串的大小必须在指定的范围内     @Length(min = 下限, max= 上限 )</p>
</li>
<li><p>@NotEmpty  被注释的字符串的必须非空CharSequence子类，Collection,Map数组等</p>
</li>
<li><p>@Range  被注释的元素必须在合适的范围内@Range(min = 下限, max= 上限), 数值类型</p>
</li>
<li><p>@Pattern(regexp=正则表达式) String,CharSequence的子类</p>
</li>
</ul>
</li>
</ul>
<p>数据验证需要的jar包(Maven工程)：<br><figure class="highlight xml"><table><tr><td class="code"><pre><div class="line"><span class="comment">&lt;!-- 自动加载validation-api的依赖 和sl4j的相关依赖 --&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.hibernate<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>hibernate-validator<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">version</span>&gt;</span>5.1.3.Final<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.slf4j<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>slf4j-log4j12<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">version</span>&gt;</span>1.6.1<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">dependency</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">groupId</span>&gt;</span>org.slf4j<span class="tag">&lt;/<span class="name">groupId</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">artifactId</span>&gt;</span>slf4j-api<span class="tag">&lt;/<span class="name">artifactId</span>&gt;</span></div><div class="line">      <span class="tag">&lt;<span class="name">version</span>&gt;</span>1.7.7<span class="tag">&lt;/<span class="name">version</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">dependency</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>数据验证在spring中的配置：<br><figure class="highlight xml"><table><tr><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">mvc:annotation-driven</span> <span class="attr">validator</span>=<span class="string">"validator"</span>/&gt;</span></div><div class="line"><span class="comment">&lt;!-- 开启数据校验 --&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"validator"</span></span></div><div class="line">	<span class="attr">class</span>=<span class="string">"org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"</span>&gt;</div><div class="line">	<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"providerClass"</span> <span class="attr">value</span>=<span class="string">"org.hibernate.validator.HibernateValidator"</span> /&gt;</span></div><div class="line">	<span class="comment">&lt;!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties --&gt;</span></div><div class="line">	<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"validationMessageSource"</span> <span class="attr">ref</span>=<span class="string">"messageSource"</span> /&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></div><div class="line"><span class="comment">&lt;!-- 数据校验的文件,解耦错误信息，便与国际化 --&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"messageSource"</span> 	</span></div><div class="line">      <span class="attr">class</span>=<span class="string">"org.springframework.context.support.ResourceBundleMessageSource"</span>&gt;</div><div class="line">		<span class="tag">&lt;<span class="name">property</span> <span class="attr">name</span>=<span class="string">"basename"</span> <span class="attr">value</span>=<span class="string">"i18n/messages"</span>/&gt;</span>	</div><div class="line"><span class="tag">&lt;/<span class="name">bean</span>&gt;</span></div></pre></td></tr></table></figure></p>
<p>实体类：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">implements</span> <span class="title">Serializable</span></span>&#123;</div><div class="line">	<span class="meta">@NotEmpty</span>(message=<span class="string">"&#123;NotEmpty.user.username&#125;"</span>)</div><div class="line">	<span class="keyword">private</span> String username;</div><div class="line">	<span class="meta">@Pattern</span>(regexp=<span class="string">"[0-9a-zA-z]&#123;6,30&#125;"</span>,message=<span class="string">"&#123;Pattern.user.password&#125;"</span>)</div><div class="line">	<span class="keyword">private</span> String password;</div><div class="line">	<span class="meta">@NotNull</span>(message=<span class="string">"&#123;NotNull.user.age&#125;"</span>)</div><div class="line">	<span class="keyword">private</span> Integer age;</div><div class="line">	<span class="meta">@Email</span>(message=<span class="string">"&#123;Email.user.email&#125;"</span>)</div><div class="line">	<span class="keyword">private</span> String email;</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getUsername</span><span class="params">()</span> </span>&#123;</div><div class="line">		<span class="keyword">return</span> username;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setUsername</span><span class="params">(String username)</span> </span>&#123;</div><div class="line">		<span class="keyword">this</span>.username = username;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getPassword</span><span class="params">()</span> </span>&#123;</div><div class="line">		<span class="keyword">return</span> password;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setPassword</span><span class="params">(String password)</span> </span>&#123;</div><div class="line">		<span class="keyword">this</span>.password = password;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> Integer <span class="title">getAge</span><span class="params">()</span> </span>&#123;</div><div class="line">		<span class="keyword">return</span> age;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAge</span><span class="params">(Integer age)</span> </span>&#123;</div><div class="line">		<span class="keyword">this</span>.age = age;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">getEmail</span><span class="params">()</span> </span>&#123;</div><div class="line">		<span class="keyword">return</span> email;</div><div class="line">	&#125;</div><div class="line">	<span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setEmail</span><span class="params">(String email)</span> </span>&#123;</div><div class="line">		<span class="keyword">this</span>.email = email;</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>控制类：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><div class="line"><span class="meta">@Controller</span></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">registerController</span> </span>&#123;</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"/register"</span>,method=RequestMethod.GET)</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">register</span><span class="params">()</span></span>&#123;</div><div class="line">		<span class="keyword">return</span> <span class="string">"register"</span>;</div><div class="line">	&#125;</div><div class="line">	<span class="comment">/*</span></div><div class="line">	 * 在对象前使用@Valid注解，后面跟BindingResult或Errors类用来保存错误信息</div><div class="line">	 */</div><div class="line">	<span class="meta">@RequestMapping</span>(value=<span class="string">"/register"</span>,method=RequestMethod.POST)</div><div class="line">	<span class="function"><span class="keyword">public</span> String <span class="title">registerUser</span><span class="params">(@Valid User User,BindingResult result,ModelMap map)</span></span>&#123;</div><div class="line">		<span class="keyword">if</span>(result.hasErrors())&#123;</div><div class="line">			List&lt;FieldError&gt; errorList = result.getFieldErrors();</div><div class="line">			<span class="keyword">for</span> (FieldError error : errorList) &#123;</div><div class="line">				map.put(<span class="string">"ERR_"</span>+error.getField(), error.getDefaultMessage());</div><div class="line">			&#125;</div><div class="line">			<span class="keyword">return</span> <span class="string">"register"</span>;<span class="comment">//返回错误因为</span></div><div class="line">		&#125;</div><div class="line">		<span class="keyword">return</span> <span class="string">"success"</span>;</div><div class="line">	&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>视图页面：</p>
<figure class="highlight html"><table><tr><td class="code"><pre><div class="line"><span class="tag">&lt;<span class="name">%@</span> <span class="attr">page</span> <span class="attr">language</span>=<span class="string">"java"</span> <span class="attr">contentType</span>=<span class="string">"text/html; charset=UTF-8"</span></span></div><div class="line">    <span class="attr">pageEncoding</span>=<span class="string">"UTF-8"</span>%&gt;</div><div class="line"><span class="meta">&lt;!DOCTYPE html&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">meta</span> <span class="attr">http-equiv</span>=<span class="string">"Content-Type"</span> <span class="attr">content</span>=<span class="string">"text/html; charset=UTF-8"</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">title</span>&gt;</span>Insert title here<span class="tag">&lt;/<span class="name">title</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></div><div class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></div><div class="line">	<span class="tag">&lt;<span class="name">h2</span>&gt;</span>系统注册<span class="tag">&lt;/<span class="name">h2</span>&gt;</span></div><div class="line">	<span class="tag">&lt;<span class="name">form</span> <span class="attr">action</span>=<span class="string">"$&#123;pageContext.request.contextPath&#125;/register"</span> <span class="attr">method</span>=<span class="string">"post"</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">p</span>&gt;</span>$&#123;ERR_username&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></div><div class="line">		姓名：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">name</span>=<span class="string">"username"</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">p</span>&gt;</span>$&#123;ERR_email&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></div><div class="line">		邮箱：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">name</span>=<span class="string">"email"</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">p</span>&gt;</span>$&#123;ERR_age&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></div><div class="line">		年龄：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">name</span>=<span class="string">"age"</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">p</span>&gt;</span>$&#123;ERR_password&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></div><div class="line">		密码：<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"password"</span> <span class="attr">name</span>=<span class="string">"password"</span>&gt;</span><span class="tag">&lt;<span class="name">br</span>&gt;</span></div><div class="line">		<span class="tag">&lt;<span class="name">input</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">value</span>=<span class="string">"注册"</span>&gt;</span></div><div class="line">	<span class="tag">&lt;/<span class="name">form</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></div><div class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></div></pre></td></tr></table></figure>
<p>可以使用springmvc标签显示错误信息<br><figure class="highlight plain"><table><tr><td class="code"><pre><div class="line">&lt;%@taglib prefix=&quot;form&quot; uri=&quot;http://www.springframework.org/tags/form&quot; %&gt;	</div><div class="line">&lt;form:form commandName=&quot;user&quot;&gt;</div><div class="line">		&lt;form:errors path=&quot;*&quot; cssStyle=&quot;color:red&quot;&gt;&lt;/form:errors&gt;&lt;br/&gt;</div><div class="line">&lt;/form:form&gt;</div></pre></td></tr></table></figure></p>
<h2 id="校验结果保存在BindingResult或Errors对象中："><a href="#校验结果保存在BindingResult或Errors对象中：" class="headerlink" title="校验结果保存在BindingResult或Errors对象中："></a>校验结果保存在BindingResult或Errors对象中：</h2><ul>
<li><p>这两个类都位于org.springframework.validation包中</p>
</li>
<li><p>需校验的表单对象和其绑定结果对象或错误对象是成对出现的</p>
</li>
<li><p>Errors接口提供了获取错误信息的方法，如getErrorCount()获取错误的数量， getFieldErrors(Stringfield)得到成员属性的校验错误列表</p>
</li>
<li>BindingResult接口扩展了Errors接口，以便可以使用Spring的org.springframeword.validation.Validator对数据进行校验，同时获取数据绑定结果对象的信息</li>
</ul>

      
    </div>

    <div>
      
        

      
    </div>

    <div>
      
        

      
    </div>


    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/tags/springmvc/" rel="tag"># springmvc</a>
          
        </div>
      

      
        
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/2017/08/13/UML学习笔记/" rel="next" title="UML学习笔记">
                <i class="fa fa-chevron-left"></i> UML学习笔记
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/2017/08/15/SpringMVC基础学习之文件的上传与下载/" rel="prev" title="SpringMVC基础学习之文件的上传与下载">
                SpringMVC基础学习之文件的上传与下载 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </article>



    <div class="post-spread">
      
    </div>
  </div>

          
          </div>
          


          
  <div class="comments" id="comments">
    
      <div id="uyan_frame"></div>
    
  </div>


        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap" >
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
          <img class="site-author-image" itemprop="image"
               src="/images/avater.png"
               alt="Tony" />
          <p class="site-author-name" itemprop="name">Tony</p>
           
              <p class="site-description motion-element" itemprop="description">学习技术，分享技术...</p>
          
        </div>
        <nav class="site-state motion-element">

          
            <div class="site-state-item site-state-posts">
              <a href="/archives">
                <span class="site-state-item-count">29</span>
                <span class="site-state-item-name">日志</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-categories">
              <a href="/categories/index.html">
                <span class="site-state-item-count">11</span>
                <span class="site-state-item-name">分类</span>
              </a>
            </div>
          

          
            
            
            <div class="site-state-item site-state-tags">
              <a href="/tags/index.html">
                <span class="site-state-item-count">25</span>
                <span class="site-state-item-name">标签</span>
              </a>
            </div>
          

        </nav>

        

        <div class="links-of-author motion-element">
          
            
              <span class="links-of-author-item">
                <a href="https://github.com/zitongchen" rel="external nofollow" target="_blank" title="GitHub">
                  
                    <i class="fa fa-fw fa-github"></i>
                  
                  GitHub
                </a>
              </span>
            
          
        </div>

        
        

        
        

        


      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#Spring的Jar包依赖和配置文件的设置"><span class="nav-number">1.</span> <span class="nav-text">Spring的Jar包依赖和配置文件的设置</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#注解控制器"><span class="nav-number">2.</span> <span class="nav-text">注解控制器</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring2-5引入注解式的处理器"><span class="nav-number">2.1.</span> <span class="nav-text">Spring2.5引入注解式的处理器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Spring3-0引入RESTful架构风格的支持"><span class="nav-number">2.2.</span> <span class="nav-text">Spring3.0引入RESTful架构风格的支持</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#请求数据绑定"><span class="nav-number">2.3.</span> <span class="nav-text">请求数据绑定</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Json返回类型"><span class="nav-number">2.4.</span> <span class="nav-text">Json返回类型</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#ModelAttribute-amp-SessionAttribute"><span class="nav-number">2.5.</span> <span class="nav-text">@ModelAttribute & @SessionAttribute</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#拦截器"><span class="nav-number">3.</span> <span class="nav-text">拦截器</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#拦截器执行顺序"><span class="nav-number">3.1.</span> <span class="nav-text">拦截器执行顺序</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#统一异常处理"><span class="nav-number">4.</span> <span class="nav-text">统一异常处理</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#数据验证"><span class="nav-number">5.</span> <span class="nav-text">数据验证</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#JSR303-校验框架介绍："><span class="nav-number">5.1.</span> <span class="nav-text">JSR303 校验框架介绍：</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#JSR303-校验框架注解类："><span class="nav-number">5.2.</span> <span class="nav-text">JSR303 校验框架注解类：</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#HibernateValidator扩展注解类："><span class="nav-number">5.3.</span> <span class="nav-text">HibernateValidator扩展注解类：</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#校验结果保存在BindingResult或Errors对象中："><span class="nav-number">5.4.</span> <span class="nav-text">校验结果保存在BindingResult或Errors对象中：</span></a></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright" >
  
  &copy; 
  <span itemprop="copyrightYear">2017</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Tony</span>
</div>


<div class="powered-by">
  由 <a class="theme-link" href="https://hexo.io" rel="external nofollow">Hexo</a> 强力驱动
</div>

<div class="theme-info">
  主题 -
  <a class="theme-link" href="https://github.com/iissnan/hexo-theme-next" rel="external nofollow">
    NexT.Mist
  </a>
</div>


        

        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    
    
  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  




  
  <script type="text/javascript" src="//cdn.jsdelivr.net/jquery/2.1.3/jquery.min.js"></script>

  
  <script type="text/javascript" src="//cdn.jsdelivr.net/fastclick/1.0.6/fastclick.min.js"></script>

  
  <script type="text/javascript" src="//cdn.jsdelivr.net/jquery.lazyload/1.9.3/jquery.lazyload.min.js"></script>

  
  <script type="text/javascript" src="//cdn.jsdelivr.net/velocity/1.2.3/velocity.min.js"></script>

  
  <script type="text/javascript" src="//cdn.jsdelivr.net/velocity/1.2.3/velocity.ui.min.js"></script>

  
  <script type="text/javascript" src="//cdn.jsdelivr.net/fancybox/2.1.5/jquery.fancybox.pack.js"></script>


  


  <script type="text/javascript" src="/js/src/utils.js?v=5.1.0"></script>

  <script type="text/javascript" src="/js/src/motion.js?v=5.1.0"></script>



  
  

  
  <script type="text/javascript" src="/js/src/scrollspy.js?v=5.1.0"></script>
<script type="text/javascript" src="/js/src/post-details.js?v=5.1.0"></script>



  


  <script type="text/javascript" src="/js/src/bootstrap.js?v=5.1.0"></script>



  



  




	





  





  
    

    
      <!-- UY BEGIN -->
      <script type="text/javascript" src="http://v2.uyan.cc/code/uyan.js?uid=2130825"></script>
      <!-- UY END -->
    
  





  



  
  

  

  

  
  <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
  <script>AV.initialize("4wyUmphSKE5wrQGHEh5Js0bk-gzGzoHsz", "oTOHrhMuED5U0oqV2KrRMGF0");</script>
  <script>
    function showTime(Counter) {
      var query = new AV.Query(Counter);
      var entries = [];
      var $visitors = $(".leancloud_visitors");

      $visitors.each(function () {
        entries.push( $(this).attr("id").trim() );
      });

      query.containedIn('url', entries);
      query.find()
        .done(function (results) {
          var COUNT_CONTAINER_REF = '.leancloud-visitors-count';

          if (results.length === 0) {
            $visitors.find(COUNT_CONTAINER_REF).text(0);
            return;
          }

          for (var i = 0; i < results.length; i++) {
            var item = results[i];
            var url = item.get('url');
            var time = item.get('time');
            var element = document.getElementById(url);

            $(element).find(COUNT_CONTAINER_REF).text(time);
          }
          for(var i = 0; i < entries.length; i++) {
            var url = entries[i];
            var element = document.getElementById(url);
            var countSpan = $(element).find(COUNT_CONTAINER_REF);
            if( countSpan.text() == '') {
              countSpan.text(0);
            }
          }
        })
        .fail(function (object, error) {
          console.log("Error: " + error.code + " " + error.message);
        });
    }

    function addCount(Counter) {
      var $visitors = $(".leancloud_visitors");
      var url = $visitors.attr('id').trim();
      var title = $visitors.attr('data-flag-title').trim();
      var query = new AV.Query(Counter);

      query.equalTo("url", url);
      query.find({
        success: function(results) {
          if (results.length > 0) {
            var counter = results[0];
            counter.fetchWhenSave(true);
            counter.increment("time");
            counter.save(null, {
              success: function(counter) {
                var $element = $(document.getElementById(url));
                $element.find('.leancloud-visitors-count').text(counter.get('time'));
              },
              error: function(counter, error) {
                console.log('Failed to save Visitor num, with error message: ' + error.message);
              }
            });
          } else {
            var newcounter = new Counter();
            /* Set ACL */
            var acl = new AV.ACL();
            acl.setPublicReadAccess(true);
            acl.setPublicWriteAccess(true);
            newcounter.setACL(acl);
            /* End Set ACL */
            newcounter.set("title", title);
            newcounter.set("url", url);
            newcounter.set("time", 1);
            newcounter.save(null, {
              success: function(newcounter) {
                var $element = $(document.getElementById(url));
                $element.find('.leancloud-visitors-count').text(newcounter.get('time'));
              },
              error: function(newcounter, error) {
                console.log('Failed to create');
              }
            });
          }
        },
        error: function(error) {
          console.log('Error:' + error.code + " " + error.message);
        }
      });
    }

    $(function() {
      var Counter = AV.Object.extend("Counter");
      if ($('.leancloud_visitors').length == 1) {
        addCount(Counter);
      } else if ($('.post-title-link').length > 1) {
        showTime(Counter);
      }
    });
  </script>



  

  


  
</body>
</html>
